from datetime import datetime, timedelta, timezone
from chinese_calendar import is_holiday  # pip install chinese_calendar
from typing import Optional, Dict, Union
import pytz


class TimeUtils:
    @staticmethod
    def get_timestamp(unit: str = 'ms') -> int:
        """
        获取当前时间戳
        :param unit: 时间单位 (ms-毫秒, s-秒)
        """
        ts = datetime.now().timestamp()
        return int(ts * 1000) if unit == 'ms' else int(ts)

    @staticmethod
    def format_time(
            dt: Optional[datetime] = None,
            fmt: str = "%Y-%m-%d %H:%M:%S",
            tz: Optional[str] = None
    ) -> str:
        """
        时间格式化
        :param dt: 时间对象，默认当前时间
        :param fmt: 格式字符串
        :param tz: 时区名称（如'Asia/Shanghai'）
        """
        dt = dt or datetime.now()
        if tz:
            dt = dt.astimezone(pytz.timezone(tz))
        return dt.strftime(fmt)

    @staticmethod
    def parse_time(
            time_str: Union[str, int, float],  # 修改此处
            fmt: str = "%Y-%m-%d %H:%M:%S",
    ) -> Optional[str]:  # 修改返回类型
        """
        解析时间字符串
        :param time_str: 时间字符串
        :param fmt: 格式字符串
        """
        if isinstance(time_str, (int, float)):
            if time_str > 1e12:  # 毫秒级时间戳
                time_str /= 1000
            return datetime.fromtimestamp(time_str).strftime(fmt)

        # 原字符串处理逻辑保持不变
        try:
            return datetime.strptime(time_str, fmt).strftime(fmt)
        except ValueError:
            pass

        alternative_formats = [
            "%Y-%m-%d",  # 年月日
            "%Y/%m/%d",  # 斜杠分隔
            "%Y%m%d",  # 无分隔
            "%Y-%m-%d %H:%M",  # 缺少秒
            "%Y-%m-%dT%H:%M:%S",  # ISO 8601
        ]

        for alt_fmt in alternative_formats:
            try:
                dt = datetime.strptime(time_str, alt_fmt)
                # 按用户指定的 fmt 格式化输出（补零时分秒）
                return dt.strftime(fmt)
            except ValueError:
                continue

        try:
            timestamp = int(time_str)
            if timestamp > 1e12:  # 毫秒级时间戳
                timestamp /= 1000
            return datetime.fromtimestamp(timestamp).strftime(fmt)
        except:
            return None

    @staticmethod
    def time_diff(
            start: datetime,
            end: datetime,
            unit: str = 'seconds'
    ) -> float:
        """
        计算时间差
        :param unit: 单位 (days, hours, minutes, seconds, milliseconds)
        """
        delta = end - start
        units = {
            'days': delta.days,
            'hours': delta.total_seconds() / 3600,
            'minutes': delta.total_seconds() / 60,
            'seconds': delta.total_seconds(),
            'milliseconds': delta.total_seconds() * 1000
        }
        return units.get(unit, delta.total_seconds())

    @staticmethod
    def is_holiday(dt: datetime) -> bool:
        """判断是否为中国节假日"""
        return is_holiday(dt)

    @staticmethod
    def get_current_datetime(pad_zero: bool = False) -> Dict[str, str]:
        """
        获取当前日期时间的各个组成部分
        :param pad_zero: 是否补零(例如：3月→"03")
        :return: 包含日期时间各部分字典
        """
        now = datetime.now()

        def _format(num: int) -> str:
            return str(num).zfill(2) if pad_zero else str(num)

        return {
            'year': str(now.year),
            'month': _format(now.month),  # Python月份直接是1-12
            'day': _format(now.day),
            'hour': _format(now.hour),
            'minute': _format(now.minute),
            'second': _format(now.second),
        }


if __name__ == '__main__':
    # 获取时间戳
    print(TimeUtils.get_timestamp())  # 默认毫秒 1744438714297
    print(TimeUtils.get_timestamp('s'))  # 秒级 1744438714

    # 时间格式化
    print(TimeUtils.format_time())  # "2025-04-12 14:18:34"
    print(TimeUtils.format_time(tz="Asia/Shanghai"))  # 上海时区时间

    # 解析时间
    dt = TimeUtils.parse_time("2025-04-12 14:18:34")
    print(dt)

    # 计算时间差
    start = datetime(2025, 4, 11)
    end = datetime(2025, 4, 12)
    print(TimeUtils.time_diff(start, end, 'hours'))  # 24.0

    # 判断是否为节假日
    print(TimeUtils.is_holiday(datetime(2025, 4, 4)))

    # 当前时间
    # 不补零
    print(TimeUtils.get_current_datetime())
    # 补零
    print(TimeUtils.get_current_datetime(pad_zero=True))

    t = TimeUtils()
    ts = '2025-04-14-09'
    ts = ts[:-3]
    print(t.parse_time(ts))